import $ from 'jquery'
function Core() {}

/**
 * 获取默认值。
 * @param {*} a
 * @param {*} b
 * @returns {*} 如果未定义，则返回第一个参数，否则返回第二个参数。
 * @example
 * param = Core.defaultValue(param, 'default');
 */
Core.prototype.defaultValue = function (a, b) {
  return defaultValue(a, b);
};

/**
 * 随机id
 * @returns {String} 返回一个随机id
 * @example
 * id = Core.createRandomId();
 */
Core.prototype.createRandomId = function () {
  return (Math.random() * 10000000).toString(16).substr(0, 4) + '-' + (new Date()).getTime() + '-' + Math.random().toString().substr(2, 5);
};

function defaultValue(a, b) {
  if (a !== undefined && a !== null) {
    return a;
  }
  return b;
}

//空间距离测量用米
Core.prototype.getSpaceDistancem = function (positions, Cesium) {
  var distance = 0;
  for (var i = 0; i < positions.length - 1; i++) {
    var point1cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
    var point2cartographic = Cesium.Cartographic.fromCartesian(positions[i + 1]);
    /**根据经纬度计算出距离**/
    var geodesic = new Cesium.EllipsoidGeodesic();
    geodesic.setEndPoints(point1cartographic, point2cartographic);
    var s = geodesic.surfaceDistance;
    //console.log(Math.sqrt(Math.pow(distance, 2) + Math.pow(endheight, 2)));
    //返回两点之间的距离
    s = (Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2)));
    distance = distance + s;
  }
  return distance.toFixed(2);
};

//水平距离测量
Core.prototype.getHorizontalDistance = function (positions, Cesium) {
  var distance = 0;
  for (var i = 0; i < positions.length - 1; i++) {

    var point1cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
    var point2cartographic = Cesium.Cartographic.fromCartesian(positions[i + 1]);
    /**根据经纬度计算出距离**/
    var geodesic = new Cesium.EllipsoidGeodesic();
    geodesic.setEndPoints(point1cartographic, point2cartographic);
    var s = geodesic.surfaceDistance;
    //console.log(Math.sqrt(Math.pow(distance, 2) + Math.pow(endheight, 2)));
    //返回两点之间的距离
    //s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
    distance = distance + s;
  }
  if (distance >= 1000) {
    distance = (distance / 1000).toFixed(2) + "千米";
  } else {
    distance = (distance.toFixed(2)) + "米";
  }
  return distance;
}

/**
 * 两点方位角
 * @param {number} lon1 起点经度
 * @param {number} lat1 起点纬度
 * @param {number} lon2 终点经度
 * @param {number} lat2 终点纬度
 */
Core.prototype.TwoPointAzimuth = function (lon1, lat1, lon2, lat2) {
  var result = 0.0;
  var getRad = function (d) {
    return d * Math.PI / 180.0;
  };

  var ilat1 = Math.round(0.50 + lat1 * 360000.0);
  var ilat2 = Math.round(0.50 + lat2 * 360000.0);
  var ilon1 = Math.round(0.50 + lon1 * 360000.0);
  var ilon2 = Math.round(0.50 + lon2 * 360000.0);

  lat1 = getRad(lat1);
  lon1 = getRad(lon1);
  lat2 = getRad(lat2);
  lon2 = getRad(lon2);

  if ((ilat1 === ilat2) && (ilon1 === ilon2)) {
    return result;
  } else if (ilon1 === ilon2) {
    if (ilat1 > ilat2)
      result = 180.0;
  } else {
    var c = Math.acos(Math.sin(lat2) * Math.sin(lat1) + Math.cos(lat2) * Math.cos(lat1) * Math.cos((lon2 - lon1)));
    var A = Math.asin(Math.cos(lat2) * Math.sin((lon2 - lon1)) / Math.sin(c));
    result = A * 180 / Math.PI;
    if ((ilat2 > ilat1) && (ilon2 > ilon1));
    else if ((ilat2 < ilat1) && (ilon2 < ilon1)) {
      result = 180.0 - result;
    } else if ((ilat2 < ilat1) && (ilon2 > ilon1)) {
      result = 180.0 - result;
    } else if ((ilat2 > ilat1) && (ilon2 < ilon1)) {
      result += 360.0;
    }
  }
  return result;
}

/**
 * 射线求交
 * 
 * @param {Viewer} Viewer 地图视图
 * @param {Cartesian3} start 起点
 * @param {Cartesian3} end 终点
 * @param {Array} objectsToExclude 排除的对象
 */
Core.prototype.pickFromRay = function (Viewer, start, end, objectsToExclude = []) {
  if (start.equals(end)) {
    return undefined;
  }
  // 计算射线的方向，目标点left 视点right
  let direction = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(end, start, new Cesium.Cartesian3()), new Cesium.Cartesian3());
  // 建立射线
  let ray = new Cesium.Ray(start, direction);
  let result = Viewer.scene.pickFromRay(ray, objectsToExclude); // 计算交互点，返回第一个
  return result;
}

Core.prototype.getuid = function () {
  return this.uuid(8, 16);
}

/**
 * 获取uuid
 */
Core.prototype.uuid = function (len, radix) {
  var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
  var uuid = [],
    i;
  var uuid = [],
    i;
  radix = radix || chars.length;

  if (len) {
    // Compact form
    for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
  } else {
    // rfc4122, version 4 form
    var r;

    // rfc4122 requires these characters
    uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
    uuid[14] = '4';

    // Fill in random data.  At i==19 set the high bits of clock sequence as
    // per rfc4122, sec. 4.1.5
    for (i = 0; i < 36; i++) {
      if (!uuid[i]) {
        r = 0 | Math.random() * 16;
        uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
      }
    }
  }

  return uuid.join('');
}


// 判断是否为手机浏览器
Core.prototype.getBrowser = function () {
  var ua = navigator.userAgent.toLowerCase();
  var btypeInfo = (ua.match(/firefox|chrome|safari|opera/g) || "other")[0];
  if ((ua.match(/msie|trident/g) || [])[0]) {
    btypeInfo = "msie";
  }
  var pc = "";
  var prefix = "";
  var plat = "";
  //如果没有触摸事件 判定为PC
  var isTocuh = ("ontouchstart" in window) || (ua.indexOf("touch") !== -1) || (ua.indexOf("mobile") !== -1);
  if (isTocuh) {
    if (ua.indexOf("ipad") !== -1) {
      pc = "pad";
    } else if (ua.indexOf("mobile") !== -1) {
      pc = "mobile";
    } else if (ua.indexOf("android") !== -1) {
      pc = "androidPad";
    } else {
      pc = "pc";
    }
  } else {
    pc = "pc";
  }
  switch (btypeInfo) {
    case "chrome":
    case "safari":
    case "mobile":
      prefix = "webkit";
      break;
    case "msie":
      prefix = "ms";
      break;
    case "firefox":
      prefix = "Moz";
      break;
    case "opera":
      prefix = "O";
      break;
    default:
      prefix = "webkit";
      break
  }
  plat = (ua.indexOf("android") > 0) ? "android" : navigator.platform.toLowerCase();
  return {
    version: (ua.match(/[\s\S]+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1], //版本
    plat: plat, //系统
    type: btypeInfo, //浏览器
    pc: pc,
    prefix: prefix, //前缀
    isMobile: (pc == "pc") ? false : true //是否是移动端
  };
}


Core.prototype.getClosetPoint = function (point, start, end) {
  // var segment = Cesium.Cartesian3.subtract(end, start, new Cesium.Cartesian3())
  // var pointToStart = Cesium.Cartesian3.subtract(point, start, new Cesium.Cartesian3())
  // var segmentLengthSqure = Cesium.Cartesian3.magnitudeSquared(segment)
  // if (segmentLengthSqure == 0) {
  //   return start
  // }
  // var t = Cesium.Cartesian3.dot(pointToStart, segment) / segmentLengthSqure
  // t = Math.max(0, Math.min(1, t))
  // var closest = new Cesium.Cartesian3(start.x + t * segment.x, start.y + t * segment.y, start.z + segment.z)
  // return closest
  var AB = new Cesium.Cartesian3(end.x - start.x, end.y - start.y, end.z - start.z)
  var AP = new Cesium.Cartesian3(point.x - start.x, point.y - start.y, point.z - start.z)
  var AB_AB = Cesium.Cartesian3.dot(AB, AB)
  var AP_AB = Cesium.Cartesian3.dot(AP, AB)
  var t = AP_AB / AB_AB
  t = Math.max(0, Math.min(1, t))
  var cloest = new Cesium.Cartesian3(start.x + t * AB.x, start.y + t * AB.y, start.z + t * AB.z)
  return cloest



}

Core.prototype.getClosetPointOfpolyline = function (clickPosition, polylinePosition) {
  var closetPoint = null
  var min = Number.MAX_VALUE
  var index = null

  for (let i = 0; i < polylinePosition.length - 1; i++) {
    var start = polylinePosition[i]
    var end = polylinePosition[i + 1]
    var closet = this.getClosetPoint(clickPosition, start, end)
    var distance = Cesium.Cartesian3.distance(clickPosition, closet)
    if (distance < min) {
      min = distance
      closetPoint = closet
      index = i
    }
  }
  return {
    position: closetPoint,
    index: index,
    distance: min
  }

}

/**
 * 创建鼠标Tooltip提示框。
 * @param {*} [styleOrText] 提示框样式或文本内容
 * @param {String} [styleOrText.origin='center'] 对齐方式(center/top/bottom)
 * @param {String} [styleOrText.color='black'] 提示框颜色(black/white/yellow)
 * @param {String} [styleOrText.id=undefined] 提示框唯一id(可选)
 * @param {Object} position 显示位置
 * @param {Boolean} show 是否显示(如果为true，styleOrText必须为显示的文本内容)
 * @returns {Tooltip} Tooltip提示框。
 * 或
 * tooltip = Core.CreateTooltip();
 * tooltip.showAt({x:500, y:500}, '这里是提示信息');
 *
 * tooltip.show(false); //隐藏提示框
 * tooltip.show(true); //显示提示框
 */
Core.prototype.CreateTooltip = function (styleOrText = {}, position, show) {
  var style, _x, _y, _color, id;
  if (typeof styleOrText === 'object') {
    style = styleOrText;
  }
  if (style && style.origin) {
    style.origin === 'center' && (_x = 15, _y = -12);
    style.origin === 'top' && (_x = 15, _y = -44);
    style.origin === 'bottom' && (_x = 15, _y = 20);
  } else {
    _x = 15, _y = 20;
  }
  if (style && style.color) {
    style.color === 'white' && (_color = 'background: rgba(255, 255, 255, 0.8);color: black;');
    style.color === 'black' && (_color = 'background: rgba(0, 0, 0, 0.5);color: white;');
    style.color === 'yellow' && (_color = 'color: black;background-color: #ffcc33;border: 1px solid white;');
  } else {
    _color = 'background: rgba(0, 0, 0, 0.5);color: white;';
  }
  if (style && style.id) {
    id = "toolTip" + style.id;
  } else {
    id = "toolTip";
  }

  var tooltip = document.getElementById(id);

  if (!tooltip) {
    var elementbottom = document.createElement("div");
    $(".cesium-viewer").append(elementbottom);
    var html = '<div id="' + id + '" style="display: none;pointer-events: none;position: absolute;z-index: 1000;opacity: 0.8;border-radius: 4px;padding: 4px 8px;white-space: nowrap;font-family:黑体;color:white;font-weight: bolder;font-size: 14px;' + _color + '"></div>';
    $('.cesium-viewer').append(html);
    tooltip = document.getElementById(id);
  }
  if (show) {
    tooltip.innerHTML = styleOrText;
    tooltip.style.left = position.x + _x + "px";
    tooltip.style.top = position.y + _y + "px";
    tooltip.style.display = "block";
  } else {
    tooltip.style.display = "none";
  }
  return {
    tooltip: tooltip,
    style: style,
    showAt: function (position, text) {
      this.tooltip.innerHTML = text;
      if (this.style && this.style.origin) {
        this.style.origin === 'center' && (_x = 15, _y = -this.tooltip.offsetHeight / 2);
        this.style.origin === 'top' && (_x = 15, _y = -this.tooltip.offsetHeight - 20);
        this.style.origin === 'bottom' && (_x = 15, _y = 20);
      } else {
        _x = 15, _y = -this.tooltip.offsetHeight / 2;
      }
      this.tooltip.style.left = position.x + _x + "px";
      this.tooltip.style.top = position.y + _y + "px";
      this.tooltip.style.display = "block";
    },
    show: function (show) {
      if (show) {
        this.tooltip.style.display = "block";
      } else {
        this.tooltip.style.display = "none";
      }
    }
  };
};

Core.prototype.toDegrees = function (cartesian) {
  let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
  return {
      lon: Cesium.Math.toDegrees(cartographic.longitude),
      lat: Cesium.Math.toDegrees(cartographic.latitude),
      height: cartographic.height
  };
};



export default Core
